package com.zxd.interview.util;


import com.zxd.interview.util.reflect.ReflectUtils;

import java.util.Collection;
import java.util.Iterator;

/**
 * 数组辅助工具类
 *
 * @author zhaoxudong
 */
@SuppressWarnings("unchecked")
public abstract class ArrayUtils {

    private ArrayUtils() {
        throw new AssertionError("工具类不允许实例化");
    }

    /**
     * 判断数组是否为空
     *
     * @param elements 数组
     * @param <T>      泛型
     * @return true为空数组
     */
    public static <T> boolean isEmpty(T[] elements) {
        return org.apache.commons.lang3.ArrayUtils.isEmpty(elements);
    }

    /**
     * array数组是否包含item元素
     *
     * @param array 数组
     * @param item
     * @return
     */
    public static <T> boolean contains(T[] array, T item) {
        return org.apache.commons.lang3.ArrayUtils.contains(array, item);
    }

    /**
     * 将 collection 转化为数组
     *
     * @param collection 集合
     * @return 数组
     */
    public static <T> T[] toArray(Collection<T> collection) {
        if (CollectionUtils.isEmpty(collection)) {
            return null;
        }
        // 反射获取元素Class
        Class<T> clazz = ReflectUtils.getElementClass(collection);
        // 反射创建数组
        T[] array = ReflectUtils.createArray(clazz, collection.size());
        Iterator<T> iterator = collection.iterator();
        int index = 0;
        while (iterator.hasNext()) {
            array[index++] = iterator.next();
        }
        return array;
    }

    public static <T> T[] toArray(T... elements) {
        return elements;
    }

    /**
     * 返回子数组, 兼容越界情况
     *
     * @param array               数组
     * @param startIndexInclusive 开始位置, 包括
     * @param endIndexExclusive   结束位置, 不包括
     * @return 子集合
     */
    public static <T> T[] subArray(T[] array, int startIndexInclusive, int endIndexExclusive) {
        return org.apache.commons.lang3.ArrayUtils.subarray(array, startIndexInclusive, endIndexExclusive);
    }

    public static <T> T[] subArray(T[] array, int startIndexInclusive) {
        return org.apache.commons.lang3.ArrayUtils.subarray(array, startIndexInclusive, length(array));
    }

    /**
     * 获取数组长度, 防止空指针
     *
     * @param array 数组
     */
    public static <T> int length(T... array) {
        return array == null ? 0 : array.length;
    }

    public static void main(String[] args) {
//        int[] intArray = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
//
//        // ---- 测试toList
//        // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
//        System.out.println(CollectionHelper.toList(NumberHelper.enboxing(intArray), 0, 0));
//        // [6, 7, 8, 9, 10]
//        System.out.println(CollectionHelper.toList(NumberHelper.enboxing(intArray), 5, 5));
//        // [1, 2, 3, 4, 5]
//        System.out.println(CollectionHelper.toList(NumberHelper.enboxing(intArray), -1, 5));
//        // [1, 2, 3, 4, 5]
//        System.out.println(CollectionHelper.toList(NumberHelper.enboxing(intArray), -10000, 5));
//        // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
//        System.out.println(CollectionHelper.toList(NumberHelper.enboxing(intArray), -2, 10000));
//        // []
//        System.out.println(CollectionHelper.toList(NumberHelper.enboxing(intArray), 10000, 5));
//
//        // ---- 测试toIntArray
//        List list = CollectionHelper.toList(NumberHelper.enboxing(intArray));
//        // {1,2,3,4,5,6,7,8,9,10}
//        System.out.println(ArrayUtils.toString(ArrayHelper.toArray(list, 0, 0)));
//        // {6,7,8,9,10}
//        System.out.println(ArrayUtils.toString(ArrayHelper.toArray(list, 5, 5)));
//        // {1,2,3,4,5}
//        System.out.println(ArrayUtils.toString(ArrayHelper.toArray(list, -10000, 5)));
//        // {1,2,3,4,5,6,7,8,9,10}
//        System.out.println(ArrayUtils.toString(ArrayHelper.toArray(list, -2, 10000)));
//        // {}
//        System.out.println(ArrayUtils.toString(ArrayHelper.toArray(list, 10000, 5)));
//
//        // ---- 测试toIntArray
//        // {1,2,3,4,5,6,7,8,9,10}
//        System.out.println(ArrayUtils.toString(ArrayHelper.toArray((Collection) list, 0, 0)));
//        // {6,7,8,9,10}
//        System.out.println(ArrayUtils.toString(ArrayHelper.toArray((Collection) list, 5, 5)));
//        // {1,2,3,4,5}
//        System.out.println(ArrayUtils.toString(ArrayHelper.toArray((Collection) list, -10000, 5)));
//        // {1,2,3,4,5,6,7,8,9,10}
//        System.out.println(ArrayUtils.toString(ArrayHelper.toArray((Collection) list, -2, 10000)));
//        // {}
//        System.out.println(ArrayUtils.toString(ArrayHelper.toArray((Collection) list, 10000, 5)));
    }


}